home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / distutils / command / bdist_msi.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  21.7 KB  |  463 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''
  5. Implements the bdist_msi command.
  6. '''
  7. import sys
  8. import os
  9. from distutils.core import Command
  10. from distutils.dir_util import remove_tree
  11. from distutils.sysconfig import get_python_version
  12. from distutils.version import StrictVersion
  13. from distutils.errors import DistutilsOptionError
  14. from distutils.util import get_platform
  15. from distutils import log
  16. import msilib
  17. from msilib import schema, sequence, text
  18. from msilib import Directory, Feature, Dialog, add_data
  19.  
  20. class PyDialog(Dialog):
  21.     '''Dialog class with a fixed layout: controls at the top, then a ruler,
  22.     then a list of buttons: back, next, cancel. Optionally a bitmap at the
  23.     left.'''
  24.     
  25.     def __init__(self, *args, **kw):
  26.         '''Dialog(database, name, x, y, w, h, attributes, title, first,
  27.         default, cancel, bitmap=true)'''
  28.         Dialog.__init__(self, *args)
  29.         ruler = self.h - 36
  30.         bmwidth = 152 * ruler / 328
  31.         self.line('BottomLine', 0, ruler, self.w, 0)
  32.  
  33.     
  34.     def title(self, title):
  35.         '''Set the title text of the dialog at the top.'''
  36.         self.text('Title', 15, 10, 320, 60, 196611, '{\\VerdanaBold10}%s' % title)
  37.  
  38.     
  39.     def back(self, title, next, name = 'Back', active = 1):
  40.         '''Add a back button with a given title, the tab-next button,
  41.         its name in the Control table, possibly initially disabled.
  42.  
  43.         Return the button, so that events can be associated'''
  44.         if active:
  45.             flags = 3
  46.         else:
  47.             flags = 1
  48.         return self.pushbutton(name, 180, self.h - 27, 56, 17, flags, title, next)
  49.  
  50.     
  51.     def cancel(self, title, next, name = 'Cancel', active = 1):
  52.         '''Add a cancel button with a given title, the tab-next button,
  53.         its name in the Control table, possibly initially disabled.
  54.  
  55.         Return the button, so that events can be associated'''
  56.         if active:
  57.             flags = 3
  58.         else:
  59.             flags = 1
  60.         return self.pushbutton(name, 304, self.h - 27, 56, 17, flags, title, next)
  61.  
  62.     
  63.     def next(self, title, next, name = 'Next', active = 1):
  64.         '''Add a Next button with a given title, the tab-next button,
  65.         its name in the Control table, possibly initially disabled.
  66.  
  67.         Return the button, so that events can be associated'''
  68.         if active:
  69.             flags = 3
  70.         else:
  71.             flags = 1
  72.         return self.pushbutton(name, 236, self.h - 27, 56, 17, flags, title, next)
  73.  
  74.     
  75.     def xbutton(self, name, title, next, xpos):
  76.         '''Add a button with a given title, the tab-next button,
  77.         its name in the Control table, giving its x position; the
  78.         y-position is aligned with the other buttons.
  79.  
  80.         Return the button, so that events can be associated'''
  81.         return self.pushbutton(name, int(self.w * xpos - 28), self.h - 27, 56, 17, 3, title, next)
  82.  
  83.  
  84.  
  85. class bdist_msi(Command):
  86.     description = 'create a Microsoft Installer (.msi) binary distribution'
  87.     user_options = [
  88.         ('bdist-dir=', None, 'temporary directory for creating the distribution'),
  89.         ('plat-name=', 'p', 'platform name to embed in generated filenames (default: %s)' % get_platform()),
  90.         ('keep-temp', 'k', 'keep the pseudo-installation tree around after ' + 'creating the distribution archive'),
  91.         ('target-version=', None, 'require a specific python version' + ' on the target system'),
  92.         ('no-target-compile', 'c', 'do not compile .py to .pyc on the target system'),
  93.         ('no-target-optimize', 'o', 'do not compile .py to .pyo (optimized)on the target system'),
  94.         ('dist-dir=', 'd', 'directory to put final built distributions in'),
  95.         ('skip-build', None, 'skip rebuilding everything (for testing/debugging)'),
  96.         ('install-script=', None, 'basename of installation script to be run afterinstallation or before deinstallation'),
  97.         ('pre-install-script=', None, 'Fully qualified filename of a script to be run before any files are installed.  This script need not be in the distribution')]
  98.     boolean_options = [
  99.         'keep-temp',
  100.         'no-target-compile',
  101.         'no-target-optimize',
  102.         'skip-build']
  103.     
  104.     def initialize_options(self):
  105.         self.bdist_dir = None
  106.         self.plat_name = None
  107.         self.keep_temp = 0
  108.         self.no_target_compile = 0
  109.         self.no_target_optimize = 0
  110.         self.target_version = None
  111.         self.dist_dir = None
  112.         self.skip_build = 0
  113.         self.install_script = None
  114.         self.pre_install_script = None
  115.  
  116.     
  117.     def finalize_options(self):
  118.         if self.bdist_dir is None:
  119.             bdist_base = self.get_finalized_command('bdist').bdist_base
  120.             self.bdist_dir = os.path.join(bdist_base, 'msi')
  121.         
  122.         short_version = get_python_version()
  123.         if self.target_version:
  124.             if not (self.skip_build) and self.distribution.has_ext_modules() and self.target_version != short_version:
  125.                 raise DistutilsOptionError, "target version can only be %s, or the '--skip_build' option must be specified" % (short_version,)
  126.             self.target_version != short_version
  127.         else:
  128.             self.target_version = short_version
  129.         self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'), ('plat_name', 'plat_name'))
  130.         if self.pre_install_script:
  131.             raise DistutilsOptionError, 'the pre-install-script feature is not yet implemented'
  132.         self.pre_install_script
  133.         if self.install_script:
  134.             for script in self.distribution.scripts:
  135.                 if self.install_script == os.path.basename(script):
  136.                     break
  137.                     continue
  138.             else:
  139.                 raise DistutilsOptionError, "install_script '%s' not found in scripts" % self.install_script
  140.         self.install_script_key = None
  141.  
  142.     
  143.     def run(self):
  144.         if not self.skip_build:
  145.             self.run_command('build')
  146.         
  147.         install = self.reinitialize_command('install', reinit_subcommands = 1)
  148.         install.prefix = self.bdist_dir
  149.         install.skip_build = self.skip_build
  150.         install.warn_dir = 0
  151.         install_lib = self.reinitialize_command('install_lib')
  152.         install_lib.compile = 0
  153.         install_lib.optimize = 0
  154.         if self.distribution.has_ext_modules():
  155.             target_version = self.target_version
  156.             if not target_version:
  157.                 if not self.skip_build:
  158.                     raise AssertionError, 'Should have already checked this'
  159.                 target_version = sys.version[0:3]
  160.             
  161.             plat_specifier = '.%s-%s' % (self.plat_name, target_version)
  162.             build = self.get_finalized_command('build')
  163.             build.build_lib = os.path.join(build.build_base, 'lib' + plat_specifier)
  164.         
  165.         log.info('installing to %s', self.bdist_dir)
  166.         install.ensure_finalized()
  167.         sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB'))
  168.         install.run()
  169.         del sys.path[0]
  170.         self.mkpath(self.dist_dir)
  171.         fullname = self.distribution.get_fullname()
  172.         installer_name = self.get_installer_filename(fullname)
  173.         installer_name = os.path.abspath(installer_name)
  174.         if os.path.exists(installer_name):
  175.             os.unlink(installer_name)
  176.         
  177.         metadata = self.distribution.metadata
  178.         author = metadata.author
  179.         if not author:
  180.             author = metadata.maintainer
  181.         
  182.         if not author:
  183.             author = 'UNKNOWN'
  184.         
  185.         version = metadata.get_version()
  186.         sversion = '%d.%d.%d' % StrictVersion(version).version
  187.         product_name = 'Python %s %s' % (self.target_version, self.distribution.get_fullname())
  188.         self.db = msilib.init_database(installer_name, schema, product_name, msilib.gen_uuid(), sversion, author)
  189.         msilib.add_tables(self.db, sequence)
  190.         props = [
  191.             ('DistVersion', version)]
  192.         if not metadata.author_email:
  193.             pass
  194.         email = metadata.maintainer_email
  195.         if email:
  196.             props.append(('ARPCONTACT', email))
  197.         
  198.         if metadata.url:
  199.             props.append(('ARPURLINFOABOUT', metadata.url))
  200.         
  201.         if props:
  202.             add_data(self.db, 'Property', props)
  203.         
  204.         self.add_find_python()
  205.         self.add_files()
  206.         self.add_scripts()
  207.         self.add_ui()
  208.         self.db.Commit()
  209.         if hasattr(self.distribution, 'dist_files'):
  210.             self.distribution.dist_files.append(('bdist_msi', self.target_version, fullname))
  211.         
  212.         if not self.keep_temp:
  213.             remove_tree(self.bdist_dir, dry_run = self.dry_run)
  214.         
  215.  
  216.     
  217.     def add_files(self):
  218.         db = self.db
  219.         cab = msilib.CAB('distfiles')
  220.         f = Feature(db, 'default', 'Default Feature', 'Everything', 1, directory = 'TARGETDIR')
  221.         f.set_current()
  222.         rootdir = os.path.abspath(self.bdist_dir)
  223.         root = Directory(db, cab, None, rootdir, 'TARGETDIR', 'SourceDir')
  224.         db.Commit()
  225.         todo = [
  226.             root]
  227.         while todo:
  228.             dir = todo.pop()
  229.             for file in os.listdir(dir.absolute):
  230.                 afile = os.path.join(dir.absolute, file)
  231.                 if os.path.isdir(afile):
  232.                     newdir = Directory(db, cab, dir, file, file, '%s|%s' % (dir.make_short(file), file))
  233.                     todo.append(newdir)
  234.                     continue
  235.                 key = dir.add_file(file)
  236.                 if file == self.install_script:
  237.                     if self.install_script_key:
  238.                         raise DistutilsOptionError, 'Multiple files with name %s' % file
  239.                     self.install_script_key
  240.                     self.install_script_key = '[#%s]' % key
  241.                     continue
  242.             
  243.         cab.commit(db)
  244.  
  245.     
  246.     def add_find_python(self):
  247.         '''Adds code to the installer to compute the location of Python.
  248.         Properties PYTHON.MACHINE, PYTHON.USER, PYTHONDIR and PYTHON will be set
  249.         in both the execute and UI sequences; PYTHONDIR will be set from
  250.         PYTHON.USER if defined, else from PYTHON.MACHINE.
  251.         PYTHON is PYTHONDIR\\python.exe'''
  252.         install_path = 'SOFTWARE\\Python\\PythonCore\\%s\\InstallPath' % self.target_version
  253.         add_data(self.db, 'RegLocator', [
  254.             ('python.machine', 2, install_path, None, 2),
  255.             ('python.user', 1, install_path, None, 2)])
  256.         add_data(self.db, 'AppSearch', [
  257.             ('PYTHON.MACHINE', 'python.machine'),
  258.             ('PYTHON.USER', 'python.user')])
  259.         add_data(self.db, 'CustomAction', [
  260.             ('PythonFromMachine', 307, 'PYTHONDIR', '[PYTHON.MACHINE]'),
  261.             ('PythonFromUser', 307, 'PYTHONDIR', '[PYTHON.USER]'),
  262.             ('PythonExe', 307, 'PYTHON', '[PYTHONDIR]\\python.exe'),
  263.             ('InitialTargetDir', 307, 'TARGETDIR', '[PYTHONDIR]')])
  264.         add_data(self.db, 'InstallExecuteSequence', [
  265.             ('PythonFromMachine', 'PYTHON.MACHINE', 401),
  266.             ('PythonFromUser', 'PYTHON.USER', 402),
  267.             ('PythonExe', None, 403),
  268.             ('InitialTargetDir', 'TARGETDIR=""', 404)])
  269.         add_data(self.db, 'InstallUISequence', [
  270.             ('PythonFromMachine', 'PYTHON.MACHINE', 401),
  271.             ('PythonFromUser', 'PYTHON.USER', 402),
  272.             ('PythonExe', None, 403),
  273.             ('InitialTargetDir', 'TARGETDIR=""', 404)])
  274.  
  275.     
  276.     def add_scripts(self):
  277.         if self.install_script:
  278.             add_data(self.db, 'CustomAction', [
  279.                 ('install_script', 50, 'PYTHON', self.install_script_key)])
  280.             add_data(self.db, 'InstallExecuteSequence', [
  281.                 ('install_script', 'NOT Installed', 6800)])
  282.         
  283.         if self.pre_install_script:
  284.             scriptfn = os.path.join(self.bdist_dir, 'preinstall.bat')
  285.             f = open(scriptfn, 'w')
  286.             f.write('rem ="""\n%1 %0\nexit\n"""\n')
  287.             f.write(open(self.pre_install_script).read())
  288.             f.close()
  289.             add_data(self.db, 'Binary', [
  290.                 ('PreInstall', msilib.Binary(scriptfn))])
  291.             add_data(self.db, 'CustomAction', [
  292.                 ('PreInstall', 2, 'PreInstall', None)])
  293.             add_data(self.db, 'InstallExecuteSequence', [
  294.                 ('PreInstall', 'NOT Installed', 450)])
  295.         
  296.  
  297.     
  298.     def add_ui(self):
  299.         db = self.db
  300.         x = y = 50
  301.         w = 370
  302.         h = 300
  303.         title = '[ProductName] Setup'
  304.         modal = 3
  305.         modeless = 1
  306.         track_disk_space = 32
  307.         add_data(db, 'Property', [
  308.             ('DefaultUIFont', 'DlgFont8'),
  309.             ('ErrorDialog', 'ErrorDlg'),
  310.             ('Progress1', 'Install'),
  311.             ('Progress2', 'installs'),
  312.             ('MaintenanceForm_Action', 'Repair'),
  313.             ('WhichUsers', 'ALL')])
  314.         add_data(db, 'TextStyle', [
  315.             ('DlgFont8', 'Tahoma', 9, None, 0),
  316.             ('DlgFontBold8', 'Tahoma', 8, None, 1),
  317.             ('VerdanaBold10', 'Verdana', 10, None, 1),
  318.             ('VerdanaRed9', 'Verdana', 9, 255, 0)])
  319.         add_data(db, 'InstallUISequence', [
  320.             ('PrepareDlg', 'Not Privileged or Windows9x or Installed', 140),
  321.             ('WhichUsersDlg', 'Privileged and not Windows9x and not Installed', 141),
  322.             ('SelectDirectoryDlg', 'Not Installed', 1230),
  323.             ('MaintenanceTypeDlg', 'Installed AND NOT RESUME AND NOT Preselected', 1250),
  324.             ('ProgressDlg', None, 1280)])
  325.         add_data(db, 'ActionText', text.ActionText)
  326.         add_data(db, 'UIText', text.UIText)
  327.         fatal = PyDialog(db, 'FatalError', x, y, w, h, modal, title, 'Finish', 'Finish', 'Finish')
  328.         fatal.title('[ProductName] Installer ended prematurely')
  329.         fatal.back('< Back', 'Finish', active = 0)
  330.         fatal.cancel('Cancel', 'Back', active = 0)
  331.         fatal.text('Description1', 15, 70, 320, 80, 196611, '[ProductName] setup ended prematurely because of an error.  Your system has not been modified.  To install this program at a later time, please run the installation again.')
  332.         fatal.text('Description2', 15, 155, 320, 20, 196611, 'Click the Finish button to exit the Installer.')
  333.         c = fatal.next('Finish', 'Cancel', name = 'Finish')
  334.         c.event('EndDialog', 'Exit')
  335.         user_exit = PyDialog(db, 'UserExit', x, y, w, h, modal, title, 'Finish', 'Finish', 'Finish')
  336.         user_exit.title('[ProductName] Installer was interrupted')
  337.         user_exit.back('< Back', 'Finish', active = 0)
  338.         user_exit.cancel('Cancel', 'Back', active = 0)
  339.         user_exit.text('Description1', 15, 70, 320, 80, 196611, '[ProductName] setup was interrupted.  Your system has not been modified.  To install this program at a later time, please run the installation again.')
  340.         user_exit.text('Description2', 15, 155, 320, 20, 196611, 'Click the Finish button to exit the Installer.')
  341.         c = user_exit.next('Finish', 'Cancel', name = 'Finish')
  342.         c.event('EndDialog', 'Exit')
  343.         exit_dialog = PyDialog(db, 'ExitDialog', x, y, w, h, modal, title, 'Finish', 'Finish', 'Finish')
  344.         exit_dialog.title('Completing the [ProductName] Installer')
  345.         exit_dialog.back('< Back', 'Finish', active = 0)
  346.         exit_dialog.cancel('Cancel', 'Back', active = 0)
  347.         exit_dialog.text('Description', 15, 235, 320, 20, 196611, 'Click the Finish button to exit the Installer.')
  348.         c = exit_dialog.next('Finish', 'Cancel', name = 'Finish')
  349.         c.event('EndDialog', 'Return')
  350.         inuse = PyDialog(db, 'FilesInUse', x, y, w, h, 19, title, 'Retry', 'Retry', 'Retry', bitmap = False)
  351.         inuse.text('Title', 15, 6, 200, 15, 196611, '{\\DlgFontBold8}Files in Use')
  352.         inuse.text('Description', 20, 23, 280, 20, 196611, 'Some files that need to be updated are currently in use.')
  353.         inuse.text('Text', 20, 55, 330, 50, 3, 'The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.')
  354.         inuse.control('List', 'ListBox', 20, 107, 330, 130, 7, 'FileInUseProcess', None, None, None)
  355.         c = inuse.back('Exit', 'Ignore', name = 'Exit')
  356.         c.event('EndDialog', 'Exit')
  357.         c = inuse.next('Ignore', 'Retry', name = 'Ignore')
  358.         c.event('EndDialog', 'Ignore')
  359.         c = inuse.cancel('Retry', 'Exit', name = 'Retry')
  360.         c.event('EndDialog', 'Retry')
  361.         error = Dialog(db, 'ErrorDlg', 50, 10, 330, 101, 65543, title, 'ErrorText', None, None)
  362.         error.text('ErrorText', 50, 9, 280, 48, 3, '')
  363.         error.pushbutton('N', 120, 72, 81, 21, 3, 'No', None).event('EndDialog', 'ErrorNo')
  364.         error.pushbutton('Y', 240, 72, 81, 21, 3, 'Yes', None).event('EndDialog', 'ErrorYes')
  365.         error.pushbutton('A', 0, 72, 81, 21, 3, 'Abort', None).event('EndDialog', 'ErrorAbort')
  366.         error.pushbutton('C', 42, 72, 81, 21, 3, 'Cancel', None).event('EndDialog', 'ErrorCancel')
  367.         error.pushbutton('I', 81, 72, 81, 21, 3, 'Ignore', None).event('EndDialog', 'ErrorIgnore')
  368.         error.pushbutton('O', 159, 72, 81, 21, 3, 'Ok', None).event('EndDialog', 'ErrorOk')
  369.         error.pushbutton('R', 198, 72, 81, 21, 3, 'Retry', None).event('EndDialog', 'ErrorRetry')
  370.         cancel = Dialog(db, 'CancelDlg', 50, 10, 260, 85, 3, title, 'No', 'No', 'No')
  371.         cancel.text('Text', 48, 15, 194, 30, 3, 'Are you sure you want to cancel [ProductName] installation?')
  372.         c = cancel.pushbutton('Yes', 72, 57, 56, 17, 3, 'Yes', 'No')
  373.         c.event('EndDialog', 'Exit')
  374.         c = cancel.pushbutton('No', 132, 57, 56, 17, 3, 'No', 'Yes')
  375.         c.event('EndDialog', 'Return')
  376.         costing = Dialog(db, 'WaitForCostingDlg', 50, 10, 260, 85, modal, title, 'Return', 'Return', 'Return')
  377.         costing.text('Text', 48, 15, 194, 30, 3, 'Please wait while the installer finishes determining your disk space requirements.')
  378.         c = costing.pushbutton('Return', 102, 57, 56, 17, 3, 'Return', None)
  379.         c.event('EndDialog', 'Exit')
  380.         prep = PyDialog(db, 'PrepareDlg', x, y, w, h, modeless, title, 'Cancel', 'Cancel', 'Cancel')
  381.         prep.text('Description', 15, 70, 320, 40, 196611, 'Please wait while the Installer prepares to guide you through the installation.')
  382.         prep.title('Welcome to the [ProductName] Installer')
  383.         c = prep.text('ActionText', 15, 110, 320, 20, 196611, 'Pondering...')
  384.         c.mapping('ActionText', 'Text')
  385.         c = prep.text('ActionData', 15, 135, 320, 30, 196611, None)
  386.         c.mapping('ActionData', 'Text')
  387.         prep.back('Back', None, active = 0)
  388.         prep.next('Next', None, active = 0)
  389.         c = prep.cancel('Cancel', None)
  390.         c.event('SpawnDialog', 'CancelDlg')
  391.         seldlg = PyDialog(db, 'SelectDirectoryDlg', x, y, w, h, modal, title, 'Next', 'Next', 'Cancel')
  392.         seldlg.title('Select Destination Directory')
  393.         version = sys.version[:3] + ' '
  394.         seldlg.text('Hint', 15, 30, 300, 40, 3, 'The destination directory should contain a Python %sinstallation' % version)
  395.         seldlg.back('< Back', None, active = 0)
  396.         c = seldlg.next('Next >', 'Cancel')
  397.         c.event('SetTargetPath', 'TARGETDIR', ordering = 1)
  398.         c.event('SpawnWaitDialog', 'WaitForCostingDlg', ordering = 2)
  399.         c.event('EndDialog', 'Return', ordering = 3)
  400.         c = seldlg.cancel('Cancel', 'DirectoryCombo')
  401.         c.event('SpawnDialog', 'CancelDlg')
  402.         seldlg.control('DirectoryCombo', 'DirectoryCombo', 15, 70, 272, 80, 393219, 'TARGETDIR', None, 'DirectoryList', None)
  403.         seldlg.control('DirectoryList', 'DirectoryList', 15, 90, 308, 136, 3, 'TARGETDIR', None, 'PathEdit', None)
  404.         seldlg.control('PathEdit', 'PathEdit', 15, 230, 306, 16, 3, 'TARGETDIR', None, 'Next', None)
  405.         c = seldlg.pushbutton('Up', 306, 70, 18, 18, 3, 'Up', None)
  406.         c.event('DirectoryListUp', '0')
  407.         c = seldlg.pushbutton('NewDir', 324, 70, 30, 18, 3, 'New', None)
  408.         c.event('DirectoryListNew', '0')
  409.         cost = PyDialog(db, 'DiskCostDlg', x, y, w, h, modal, title, 'OK', 'OK', 'OK', bitmap = False)
  410.         cost.text('Title', 15, 6, 200, 15, 196611, '{\\DlgFontBold8}Disk Space Requirements')
  411.         cost.text('Description', 20, 20, 280, 20, 196611, 'The disk space required for the installation of the selected features.')
  412.         cost.text('Text', 20, 53, 330, 60, 3, 'The highlighted volumes (if any) do not have enough disk space available for the currently selected features.  You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).')
  413.         cost.control('VolumeList', 'VolumeCostList', 20, 100, 330, 150, 393223, None, '{120}{70}{70}{70}{70}', None, None)
  414.         cost.xbutton('OK', 'Ok', None, 0.5).event('EndDialog', 'Return')
  415.         whichusers = PyDialog(db, 'WhichUsersDlg', x, y, w, h, modal, title, 'AdminInstall', 'Next', 'Cancel')
  416.         whichusers.title('Select whether to install [ProductName] for all users of this computer.')
  417.         g = whichusers.radiogroup('AdminInstall', 15, 60, 260, 50, 3, 'WhichUsers', '', 'Next')
  418.         g.add('ALL', 0, 5, 150, 20, 'Install for all users')
  419.         g.add('JUSTME', 0, 25, 150, 20, 'Install just for me')
  420.         whichusers.back('Back', None, active = 0)
  421.         c = whichusers.next('Next >', 'Cancel')
  422.         c.event('[ALLUSERS]', '1', 'WhichUsers="ALL"', 1)
  423.         c.event('EndDialog', 'Return', ordering = 2)
  424.         c = whichusers.cancel('Cancel', 'AdminInstall')
  425.         c.event('SpawnDialog', 'CancelDlg')
  426.         progress = PyDialog(db, 'ProgressDlg', x, y, w, h, modeless, title, 'Cancel', 'Cancel', 'Cancel', bitmap = False)
  427.         progress.text('Title', 20, 15, 200, 15, 196611, '{\\DlgFontBold8}[Progress1] [ProductName]')
  428.         progress.text('Text', 35, 65, 300, 30, 3, 'Please wait while the Installer [Progress2] [ProductName]. This may take several minutes.')
  429.         progress.text('StatusLabel', 35, 100, 35, 20, 3, 'Status:')
  430.         c = progress.text('ActionText', 70, 100, w - 70, 20, 3, 'Pondering...')
  431.         c.mapping('ActionText', 'Text')
  432.         c = progress.control('ProgressBar', 'ProgressBar', 35, 120, 300, 10, 65537, None, 'Progress done', None, None)
  433.         c.mapping('SetProgress', 'Progress')
  434.         progress.back('< Back', 'Next', active = False)
  435.         progress.next('Next >', 'Cancel', active = False)
  436.         progress.cancel('Cancel', 'Back').event('SpawnDialog', 'CancelDlg')
  437.         maint = PyDialog(db, 'MaintenanceTypeDlg', x, y, w, h, modal, title, 'Next', 'Next', 'Cancel')
  438.         maint.title('Welcome to the [ProductName] Setup Wizard')
  439.         maint.text('BodyText', 15, 63, 330, 42, 3, 'Select whether you want to repair or remove [ProductName].')
  440.         g = maint.radiogroup('RepairRadioGroup', 15, 108, 330, 60, 3, 'MaintenanceForm_Action', '', 'Next')
  441.         g.add('Repair', 0, 18, 200, 17, '&Repair [ProductName]')
  442.         g.add('Remove', 0, 36, 200, 17, 'Re&move [ProductName]')
  443.         maint.back('< Back', None, active = False)
  444.         c = maint.next('Finish', 'Cancel')
  445.         c.event('[REINSTALL]', 'ALL', 'MaintenanceForm_Action="Repair"', 5)
  446.         c.event('[Progress1]', 'Repairing', 'MaintenanceForm_Action="Repair"', 6)
  447.         c.event('[Progress2]', 'repairs', 'MaintenanceForm_Action="Repair"', 7)
  448.         c.event('Reinstall', 'ALL', 'MaintenanceForm_Action="Repair"', 8)
  449.         c.event('[REMOVE]', 'ALL', 'MaintenanceForm_Action="Remove"', 11)
  450.         c.event('[Progress1]', 'Removing', 'MaintenanceForm_Action="Remove"', 12)
  451.         c.event('[Progress2]', 'removes', 'MaintenanceForm_Action="Remove"', 13)
  452.         c.event('Remove', 'ALL', 'MaintenanceForm_Action="Remove"', 14)
  453.         c.event('EndDialog', 'Return', 'MaintenanceForm_Action<>"Change"', 20)
  454.         maint.cancel('Cancel', 'RepairRadioGroup').event('SpawnDialog', 'CancelDlg')
  455.  
  456.     
  457.     def get_installer_filename(self, fullname):
  458.         base_name = '%s.%s-py%s.msi' % (fullname, self.plat_name, self.target_version)
  459.         installer_name = os.path.join(self.dist_dir, base_name)
  460.         return installer_name
  461.  
  462.  
  463.